package com.ygqh.baby.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ygqh.baby.ao.DataStatus;
import com.ygqh.baby.ao.PromotionType;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.mapper.YgSkuMapper;
import com.ygqh.baby.model.*;
import com.ygqh.baby.po.YgSku;
import com.ygqh.baby.po.YgSkuExample;
import com.ygqh.baby.po.YgSkuExample.Criteria;
import com.ygqh.baby.service.YgSkuService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
public class YgSkuServiceImpl implements YgSkuService {

    @Autowired
    private YgSkuMapper ygSkuMapper;

    @Override
    public List<YgSku> find() {
        YgSkuExample example = new YgSkuExample();
        example.createCriteria().andStatusNotEqualTo(DataStatus.Delete.name());
        return ygSkuMapper.selectByExample(example);
    }

    @Override
    public int findCount() {
        YgSkuExample example = new YgSkuExample();
        example.createCriteria().andStatusNotEqualTo(DataStatus.Delete.name());
        return ygSkuMapper.countByExample(example);
    }

    @Override
    public YgSku findById(Long id) {
        return ygSkuMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<YgSku> findByIds(Long[] ids) {
        YgSkuExample example = new YgSkuExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andIdIn(Arrays.asList(ids));

        return ygSkuMapper.selectByExample(example);
    }

    @Override
    public int save(YgSku ygSku) {
        return ygSkuMapper.insertSelective(ygSku);
    }

    @Override
    public int update(YgSku ygSku) {
        return ygSkuMapper.updateByPrimaryKeySelective(ygSku);
    }

    @Override
    public int updateByProductId(YgSku ygSku) {
        return ygSkuMapper.updateByProductId(ygSku);
    }

    @Override
    public ResultSet<YgSku> search(QueryInfo queryInfo, String q) {
        List<YgSku> list = ygSkuMapper.selectSuper(queryInfo, q);
        int count = ygSkuMapper.countSuper(q);
        ResultSet<YgSku> resultSet = new ResultSet<YgSku>(count, list);
        return resultSet;
    }

    @Override
    public int deleteSoft(Long[] ids) {
        Assert.notEmpty(ids);
        int count = 0;
        for (Long id : ids) {
            YgSku ygSku = this.findById(id);
            ygSku.setStatus(DataStatus.Delete);
            count += ygSkuMapper.updateByPrimaryKeySelective(ygSku);
        }

        return count;
    }

    @Override
    public int deleteSoft(Long id) {
        return this.deleteSoft(new Long[]{id});
    }

    @Override
    public int saveOrUpdate(YgSku ygSku) {
        int r = 0;
        if (ygSku.getId() != null) {
            r = this.update(ygSku);
        } else {
            r = this.save(ygSku);
        }
        return r;
    }

    @Override
    public List<YgSku> find(Long productId) {
        YgSkuExample example = new YgSkuExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andProductIdEqualTo(productId);
        return ygSkuMapper.selectByExample(example);
    }

    @Override
    public int saveBatch(List<YgSku> skus) {
        return ygSkuMapper.saveBatch(skus);
    }

    @Override
    public Long[] findSkuIdsByGroupId(Long groupId) {
        return ygSkuMapper.findSkuIdsByGroupId(groupId);
    }

    @Override
    public Long[] findSkuIdsWithBrandAndCategory(Long productId) {
        return ygSkuMapper.findSkuIdsWithBrandAndCategory(productId);
    }

    @Override
    public Long[] findSkuIdsWithBrandOrCategory(Long productId) {
        return ygSkuMapper.findSkuIdsWithBrandOrCategory(productId);
    }

    @Override
    public Boolean skuCodeExist(String skuCode, Long excludeId) {
        YgSkuExample example = new YgSkuExample();
        Criteria criteria = example.createCriteria().andStatusNotEqualTo(DataStatus.Delete.name()).andSkuCodeEqualTo(skuCode);
        if (excludeId != null) {
            criteria.andIdNotEqualTo(excludeId);
        }
        int count = ygSkuMapper.countByExample(example);
        if (count >= 1) {
            return true;
        }
        return false;
    }

    @Override
    public int addSkuInBatch(List<YgSku> skuList) {
        return ygSkuMapper.insertSkuInBatch(skuList);
    }

    @Override
    public YgOrder4ImportModel findOrder4ImportModel(String skuCode) {
        return ygSkuMapper.findOrder4ImportModel(skuCode);
    }

    @Override
    public YgSku findBySkuCode(String skuCode, PromotionType type) {
        List<YgSku> skuList = ygSkuMapper.selectBySkuCode(skuCode, type);
        YgSku ygsku = null;
        if (!skuList.isEmpty()) {
            ygsku = skuList.get(0);
        }
        return ygsku;
    }

    @Override
    public void updateSalesPrice(Long productId, BigDecimal productSalePrice, BigDecimal vipPrice, BigDecimal promotionPrice, BigDecimal distributionPrice) {
        ygSkuMapper.updateSkuSalesPrice(productId, productSalePrice, vipPrice, promotionPrice, distributionPrice);

    }

    @Override
    public List<YgSkuTemplate> findSkuTemplate() {
        return ygSkuMapper.findSkuTemplate();
    }

    @Override
    public List<YgSku> selectWithStock(Long productId, String sizeName) {
        return ygSkuMapper.selectWithStock(productId, sizeName);
    }

    @Override
    public List<Map<String, Object>> selectSkuCost(String productCode, String productName, String skuCode, Long groupId) {
        return ygSkuMapper.selectSkuCost(productCode, productName, skuCode, groupId);
    }

    @Override
    public void updatePromotionPrice(BigDecimal promotionPrice, Long id, String updateBy, Date updateTime, BigDecimal vipRate, BigDecimal distributionPrice) {
        ygSkuMapper.updatePromotionPrice(promotionPrice, id, updateBy, updateTime, vipRate, distributionPrice);

    }

    @Override
    public String getSkuCodes(String productIds) {
        List<String> skuCodes = ygSkuMapper.selectSkuCodes(java.util.Arrays.asList(productIds.split(",")));
        String join = StringUtils.join(skuCodes, ",");
        return join;
    }

    @Override
    public List<YgSkuReport> getSkuReport(String productCode, Date startDate, Date endDate) {
        return ygSkuMapper.getSkuReport(productCode, startDate, endDate);
    }

    @Override
    public YgSkuInfo getSkuInfo(String skuCode, PromotionType pType) {
        return ygSkuMapper.getSkuInfo(skuCode, pType);
    }

    @Override
    public List<YgSkuInfo> getSkuInfoList(List<String> productIds) {
        return ygSkuMapper.getSkuInfoList(productIds);
    }

    @Override
    public List<YgSkuInfo> getSkuInfoList(QueryInfo queryInfo, String productName, String productCode, Long supplierId, Boolean hasSkuSupplierPrice) {
        return ygSkuMapper.selectSkuInfoList(queryInfo, productName, productCode, supplierId, hasSkuSupplierPrice);
    }

    @Override
    public ResultSet<YgSkuInfo> search(QueryInfo queryInfo, String productName, String productCode, Long supplierId, Boolean hasSkuSupplierPrice) {
        List<YgSkuInfo> list = this.getSkuInfoList(queryInfo, productName, productCode, supplierId, hasSkuSupplierPrice);
        int count = ygSkuMapper.countSkuInfo(productName, productCode, supplierId, hasSkuSupplierPrice);
        ResultSet<YgSkuInfo> resultSet = new ResultSet<>(count, list);
        return resultSet;
    }

    @Override
    public YgSkuInfo findSkuInfoById(Long id) {
        return ygSkuMapper.selectSkuInfoById(id);
    }

    @Override
    public List<YgSkuInfo> findSkuInfoListByIds(List<Long> skuIds) {
        return ygSkuMapper.selectSkuInfoListByIds(skuIds);
    }

    @Override
    public boolean checkSkuInfoIsGroup(String skuInfos) {
        List<BaseSkuInfo> skuList = JSON.parseObject(skuInfos, new TypeReference<List<BaseSkuInfo>>() {
        });
        YgSku sku = this.findById(skuList.get(0).getSkuId());
        if (sku.getPromotionPrice() != null && sku.getPromotionPrice().compareTo(BigDecimal.ZERO) > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public SkuBasicData getBasicDataBySkuId(Long skuId) {
        return ygSkuMapper.getSkuBasicDataBySkuId(skuId);
    }

    @Override
    public SkuBasicData getBasicDataBySkuCode(String skuCode) {
        return ygSkuMapper.getSkuBasicDataBySkuCode(skuCode);
    }

    @Override
    public Long findMaxSkuCode(String productCode) {
        return ygSkuMapper.selectMaxSkuCode(productCode);
    }

    @Override
    public List<SkuBasicData> getBasicDataByBarCode(PromotionType pType, String... barCodes) {
        return ygSkuMapper.getBasicDataList(pType, null, barCodes, null, DataStatus.Valid);
    }

    @Override
    public List<SkuBasicData> getBasicDataBySkuCode(PromotionType pType, String... skuCodes) {
        return ygSkuMapper.getBasicDataList(pType, null, null, skuCodes, DataStatus.Valid);
    }

    @Override
    public List<SkuBasicData> getBasicDataBySkuCode(PromotionType pType, DataStatus dataStatus, String... skuCodes) {
        return ygSkuMapper.getBasicDataList(pType, null, null, skuCodes, dataStatus);
    }

    @Override
    public List<SkuBasicData> getBasicDataList(PromotionType pType, String productName) {
        return ygSkuMapper.getBasicDataList(pType, productName, null, null, DataStatus.Valid);
    }

    @Override
    public List<SkuMatchInfo> getSkuMatchInfoByProductIds(String[] productIds) {
        List<YgSku> skuList = ygSkuMapper.selectSizeInfoHasStockByProductIds(productIds);
        if (CollectionUtils.isEmpty(skuList)) {
            return new ArrayList<>();
        }
        Map<String, SkuMatchInfo> collect = new HashMap<>();
        for (YgSku sku : skuList) {
            String key;
            if (sku.getSizeName().startsWith("90")) {
                key = "90";
            } else if (sku.getSizeName().length() <= 3) {
                key = sku.getSizeName();
            } else {
                key = sku.getSizeName().substring(0, 3);
            }
            SkuMatchInfo skuMatchInfo = collect.get(key);
            if (skuMatchInfo == null) {
                skuMatchInfo = new SkuMatchInfo(sku.getId(), processSkuMatchSize(sku.getSizeName()));
            }
            skuMatchInfo.addSkuId(sku.getId()).addCount();
            collect.put(key, skuMatchInfo);
        }

        List<SkuMatchInfo> infoList = new ArrayList<>(collect.values());
        infoList.sort(Comparator.comparing(SkuMatchInfo::getSortKey));
        return infoList;
    }

    @Override
    public boolean hasDiffPrice(Long productId) {
        return ygSkuMapper.hasDiffPrice(productId) > 1;
    }

    @Override
    public YgSkuInfo findSkuInfoBySkuCode(String skuCode, PromotionType pType) {
        return ygSkuMapper.selectSkuInfoBySkuCode(skuCode, pType);
    }

    private String processSkuMatchSize(String sizeName) {
        // TODO 暂时处理逻辑
        if (sizeName != null && sizeName.contains("/")) {
            StringBuilder sb = new StringBuilder();
            sb.append(sizeName, 0, sizeName.indexOf("/"));
            if (sizeName.contains("(")) {
                sb.append(sizeName, sizeName.indexOf("("), sizeName.length());
            }
            sizeName = sb.toString();
        }
        return sizeName;
    }
}
